package com.jim.healio.tools;

import com.jim.healio.graphrag.model.MedicalEntity;
import com.jim.healio.graphrag.model.DocumentSearchResult;
import com.jim.healio.graphrag.service.GraphRAGService;
import com.jim.healio.graphrag.service.EntityValidationService;
import org.springframework.ai.tool.annotation.Tool;
import org.springframework.ai.tool.annotation.ToolParam;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.List;
import java.util.Arrays;
import java.util.ArrayList;
import java.util.stream.Collectors;

@Component
public class GraphRAGTool {
    
    private static final Logger logger = LoggerFactory.getLogger(GraphRAGTool.class);
    
    @Autowired
    private GraphRAGService graphRAGService;
    
    @Autowired
    private EntityValidationService entityValidationService;
    
    @Tool(name = "查询医学知识", description = "通过GraphRAG查询医学知识图谱，获取疾病、症状、药物等医学实体信息和相关文档")
    public String queryMedicalKnowledge(
        @ToolParam(description = "查询问题或关键词，如：糖尿病治疗、高血压药物、头痛症状等") String query,
        @ToolParam(description = "是否包含详细文档支持，true表示返回相关文档内容") boolean includeDocuments
    ) {
        try {
            logger.info("Bob调用GraphRAG查询医学知识: {}", query);
            
            StringBuilder result = new StringBuilder();
            
            // 1. 查询相关医学实体
            List<MedicalEntity> entities = graphRAGService.queryEntities(query);
            
            if (!entities.isEmpty()) {
                result.append("## 🏥 医学知识图谱分析:\n\n");
                
                for (MedicalEntity entity : entities) {
                    result.append(String.format("### %s (%s)\n", 
                        entity.getName(), entity.getType().getDescription()));
                    result.append(entity.getDescription()).append("\n\n");
                    
                    // 添加实体属性信息
                    if (!entity.getProperties().isEmpty()) {
                        result.append("**重要属性**: ");
                        entity.getProperties().forEach((key, value) -> 
                            result.append(String.format("%s: %s; ", key, value)));
                        result.append("\n\n");
                    }
                }
            }
            
            // 2. 如果需要文档支持，进行语义搜索
            if (includeDocuments) {
                List<DocumentSearchResult> documents = graphRAGService.semanticSearch(query, 3);
                
                if (!documents.isEmpty()) {
                    result.append("## 📚 相关文档支持:\n\n");
                    
                    for (DocumentSearchResult doc : documents) {
                        result.append(String.format("### %s (相似度: %s)\n", 
                            doc.getTitle(), doc.getFormattedSimilarity()));
                        result.append(doc.getContent()).append("\n\n");
                    }
                }
            }
            
            if (result.length() == 0) {
                result.append("未找到相关的医学知识信息。建议调整查询关键词或咨询其他医学资源。");
            }
            
            return result.toString();
            
        } catch (Exception e) {
            logger.error("GraphRAG查询过程中发生错误", e);
            return "查询医学知识时发生错误，请稍后重试。错误信息: " + e.getMessage();
        }
    }
    
    @Tool(name = "分析症状关联", description = "分析多个症状之间的关联性，识别可能的疾病或病理状态")
    public String analyzeSymptomRelations(
        @ToolParam(description = "症状列表，用逗号分隔，如：头痛,发热,颈项强直") String symptoms
    ) {
        try {
            logger.info("Bob调用症状关联分析: {}", symptoms);
            
            List<String> symptomList = Arrays.asList(symptoms.split(","))
                .stream()
                .map(String::trim)
                .collect(Collectors.toList());
            
            StringBuilder result = new StringBuilder();
            result.append("## 🔍 症状关联性分析:\n\n");
            result.append(String.format("**分析症状**: %s\n\n", String.join("、", symptomList)));
            
            // 1. 验证症状实体
            List<String> validatedSymptoms = new ArrayList<>();
            List<String> invalidSymptoms = new ArrayList<>();
            
            for (String symptom : symptomList) {
                EntityValidationService.EntityResolutionResult resolution = 
                    entityValidationService.resolveEntity(symptom);
                
                if (resolution.isResolved()) {
                    validatedSymptoms.add(resolution.getEntityName());
                } else {
                    invalidSymptoms.add(symptom);
                }
            }
            
            // 2. 报告验证结果
            if (!invalidSymptoms.isEmpty()) {
                result.append("⚠️ **症状验证警告**:\n");
                for (String invalidSymptom : invalidSymptoms) {
                    result.append(String.format("- '%s' 在知识图谱中未找到精确匹配\n", invalidSymptom));
                    
                    // 提供建议
                    List<EntityValidationService.EntitySuggestion> suggestions = 
                        entityValidationService.findSimilarEntities(invalidSymptom, 3);
                    if (!suggestions.isEmpty()) {
                        result.append("  建议使用: ");
                        result.append(suggestions.stream()
                            .map(EntityValidationService.EntitySuggestion::getEntityName)
                            .collect(Collectors.joining("、")));
                        result.append("\n");
                    }
                }
                result.append("\n");
            }
            
            // 3. 使用验证过的症状进行分析
            List<MedicalEntity> relatedEntities;
            if (!validatedSymptoms.isEmpty()) {
                relatedEntities = graphRAGService.analyzeSymptomRelations(validatedSymptoms);
                result.append(String.format("**✅ 已验证症状**: %s\n\n", String.join("、", validatedSymptoms)));
            } else {
                relatedEntities = new ArrayList<>();
                result.append("❌ **没有有效的症状实体可供分析**\n\n");
            }
            
            if (!relatedEntities.isEmpty()) {
                result.append("**可能相关的疾病或状态**:\n\n");
                
                for (MedicalEntity entity : relatedEntities) {
                    result.append(String.format("### %s\n", entity.getName()));
                    result.append(entity.getDescription()).append("\n");
                    
                    if (entity.getProperties().containsKey("risk_level")) {
                        result.append(String.format("**风险等级**: %s\n", 
                            entity.getProperties().get("risk_level")));
                    }
                    result.append("\n");
                }
                
                result.append("⚠️ **重要提示**: 以上分析仅供参考，具体诊断需要结合患者完整病史、体格检查和必要的辅助检查。\n");
            } else {
                result.append("暂未发现明显的症状关联模式。建议：\n");
                result.append("1. 详细了解症状的时间顺序和严重程度\n");
                result.append("2. 进行全面的病史询问和体格检查\n");
                result.append("3. 根据临床表现考虑相关的辅助检查\n");
            }
            
            return result.toString();
            
        } catch (Exception e) {
            logger.error("症状关联分析过程中发生错误", e);
            return "症状关联分析时发生错误，请稍后重试。错误信息: " + e.getMessage();
        }
    }
    
    @Tool(name = "查询药物相互作用", description = "查询多种药物之间的相互作用，识别潜在的用药风险")
    public String queryDrugInteractions(
        @ToolParam(description = "药物名称列表，用逗号分隔，如：华法林,阿司匹林") String drugs
    ) {
        try {
            logger.info("Bob调用药物相互作用查询: {}", drugs);
            
            List<String> drugList = Arrays.asList(drugs.split(","))
                .stream()
                .map(String::trim)
                .collect(Collectors.toList());
            
            List<MedicalEntity> interactions = graphRAGService.queryDrugInteractions(drugList);
            
            StringBuilder result = new StringBuilder();
            result.append("## 💊 药物相互作用分析:\n\n");
            result.append(String.format("**分析药物**: %s\n\n", String.join("、", drugList)));
            
            if (!interactions.isEmpty()) {
                result.append("**发现的药物相互作用**:\n\n");
                
                for (MedicalEntity interaction : interactions) {
                    result.append(String.format("### %s\n", interaction.getName()));
                    result.append(interaction.getDescription()).append("\n");
                    
                    if (interaction.getProperties().containsKey("risk_level")) {
                        String riskLevel = (String) interaction.getProperties().get("risk_level");
                        String riskEmoji = getRiskEmoji(riskLevel);
                        result.append(String.format("**风险等级**: %s %s\n", riskEmoji, riskLevel));
                    }
                    
                    if (interaction.getProperties().containsKey("monitoring_required") &&
                        (Boolean) interaction.getProperties().get("monitoring_required")) {
                        result.append("**监测要求**: ✅ 需要密切监测\n");
                    }
                    result.append("\n");
                }
                
                result.append("⚠️ **用药建议**:\n");
                result.append("1. 密切监测患者的临床表现和相关指标\n");
                result.append("2. 考虑调整药物剂量或更换替代药物\n");
                result.append("3. 向患者详细说明用药注意事项\n");
                result.append("4. 定期复查相关实验室指标\n");
                
            } else {
                result.append("✅ **暂未发现明显的药物相互作用**\n\n");
                result.append("但仍建议：\n");
                result.append("1. 定期监测患者的用药反应\n");
                result.append("2. 注意观察任何异常症状\n");
                result.append("3. 按照药物说明书的指导使用\n");
            }
            
            return result.toString();
            
        } catch (Exception e) {
            logger.error("药物相互作用查询过程中发生错误", e);
            return "药物相互作用查询时发生错误，请稍后重试。错误信息: " + e.getMessage();
        }
    }
    
    @Tool(name = "获取治疗指南", description = "获取特定疾病或症状的标准治疗指南和临床建议")
    public String getTreatmentGuidelines(
        @ToolParam(description = "疾病或症状名称，如：高血压、糖尿病、心律失常等") String condition
    ) {
        try {
            logger.info("Bob调用治疗指南查询: {}", condition);
            
            List<DocumentSearchResult> guidelines = graphRAGService.getTreatmentGuidelines(condition);
            
            StringBuilder result = new StringBuilder();
            result.append(String.format("## 📋 %s 治疗指南:\n\n", condition));
            
            if (!guidelines.isEmpty()) {
                for (int i = 0; i < guidelines.size(); i++) {
                    DocumentSearchResult guideline = guidelines.get(i);
                    result.append(String.format("### %d. %s\n", i + 1, guideline.getTitle()));
                    result.append(guideline.getContent()).append("\n\n");
                    
                    if (guideline.isHighRelevance()) {
                        result.append("⭐ **高度相关**\n\n");
                    }
                }
                
                result.append("📝 **临床应用建议**:\n");
                result.append("1. 指南建议应结合患者具体情况个性化应用\n");
                result.append("2. 注意患者的合并症和禁忌症\n");
                result.append("3. 定期评估治疗效果并调整方案\n");
                result.append("4. 加强患者教育和随访管理\n");
                
            } else {
                result.append("暂未找到相关的治疗指南。建议：\n");
                result.append("1. 查阅最新的专业医学文献\n");
                result.append("2. 参考相关专科学会的临床指南\n");
                result.append("3. 咨询相关专科医师的意见\n");
            }
            
            return result.toString();
            
        } catch (Exception e) {
            logger.error("治疗指南查询过程中发生错误", e);
            return "治疗指南查询时发生错误，请稍后重试。错误信息: " + e.getMessage();
        }
    }
    
    @Tool(name = "验证和建议实体", description = "验证实体是否存在于知识图谱中，如果不存在则提供相似实体建议")
    public String validateAndSuggestEntities(
        @ToolParam(description = "要验证的实体名称列表，用逗号分隔") String entities
    ) {
        try {
            logger.info("Bob调用实体验证和建议: {}", entities);
            
            List<String> entityList = Arrays.asList(entities.split(","))
                .stream()
                .map(String::trim)
                .collect(Collectors.toList());
            
            StringBuilder result = new StringBuilder();
            result.append("## 🔍 实体验证和建议结果:\n\n");
            
            for (String entity : entityList) {
                result.append(String.format("### 实体: %s\n", entity));
                
                // 智能解析实体
                EntityValidationService.EntityResolutionResult resolution = 
                    entityValidationService.resolveEntity(entity);
                
                if (resolution.isResolved()) {
                    result.append(String.format("✅ **验证成功**: %s (置信度: %.1f%%)\n", 
                        resolution.getEntityName(), resolution.getConfidence() * 100));
                    result.append(String.format("**解析结果**: %s\n", resolution.getReason()));
                } else {
                    result.append("❌ **验证失败**: 未找到精确匹配的实体\n");
                    result.append(String.format("**原因**: %s\n", resolution.getReason()));
                    
                    if (!resolution.getSuggestions().isEmpty()) {
                        result.append("**💡 相似实体建议**:\n");
                        for (EntityValidationService.EntitySuggestion suggestion : resolution.getSuggestions()) {
                            result.append(String.format("- %s (%s, 相似度: %.1f%%)\n",
                                suggestion.getEntityName(),
                                suggestion.getEntityType().getDescription(),
                                suggestion.getSimilarity() * 100));
                        }
                        result.append("\n**建议**: 请使用上述建议中的实体名称重新查询。\n");
                    } else {
                        result.append("**建议**: 请检查实体名称是否正确，或尝试使用更通用的术语。\n");
                    }
                }
                result.append("\n");
            }
            
            // 添加实体使用指导
            result.append("## 📝 实体使用指导:\n");
            result.append("- **疾病实体**: ").append(entityValidationService.getEntityHints(MedicalEntity.EntityType.DISEASE)).append("\n");
            result.append("- **药物实体**: ").append(entityValidationService.getEntityHints(MedicalEntity.EntityType.DRUG)).append("\n");
            result.append("- **症状实体**: ").append(entityValidationService.getEntityHints(MedicalEntity.EntityType.SYMPTOM)).append("\n");
            
            return result.toString();
            
        } catch (Exception e) {
            logger.error("实体验证和建议过程中发生错误", e);
            return "实体验证和建议时发生错误，请稍后重试。错误信息: " + e.getMessage();
        }
    }
    
    /**
     * 根据风险等级返回对应的表情符号
     */
    private String getRiskEmoji(String riskLevel) {
        if (riskLevel == null) return "";
        
        switch (riskLevel.toLowerCase()) {
            case "高风险": return "🔴";
            case "中风险": return "🟡";
            case "低风险": return "🟢";
            default: return "⚪";
        }
    }
} 